/**
 * Pangolin IM Server
 * autor:   yiyefangzhou24
 * email:   yiyefangzhou24@qq.com
 * data:    21/10/1
 */

#include "db_mysql.h"

MYSQL mysql;
char m_host[MAX_NAME] = { 0 };
int m_port = 0;
char m_user[MAX_NAME] = { 0 };
char m_pass[MAX_NAME] = { 0 };
char m_db[MAX_NAME] = { 0 };

int _mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);

bool init_mysql_pool(char * host , int port , char * user , char * pass , char * db){
    strcpy(m_host , host);
    m_port = port;
    strcpy(m_user , user);
    strcpy(m_pass , pass);
    strcpy(m_db , db);

    if (mysql_init(&mysql) != NULL){
        char value = 1;
        mysql_options(&mysql, MYSQL_OPT_RECONNECT, &value);
        if (mysql_real_connect(&mysql , host , user , pass , db , port , NULL , 0) != NULL){
            return true;
        }
    }
    return false;
}

void close_mysql_pool(){
    mysql_close(&mysql);
}

const char * mysql_getlasterror(){
    return mysql_error(&mysql);
}

int mysql_count_row(char * table , char * where){
    int num = 0;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "select count(*) from `%s` %s" , table , where);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL &&  mysql_field_count(&mysql) > 0 && mysql_num_rows(res) > 0) {
            MYSQL_ROW row = mysql_fetch_row(res);
            num = atoi(row[0]);
        }
        mysql_free_result(res);
    }
    return num;
}

int mysql_get_allfriendlist(int ** list){
    int num = 0;
    char query_str[MAX_SQL_LEN] = "select * from `user_relationship` where `remark` = 1";
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL ) {
            num = mysql_num_rows(res);
            for(int i = 0 ; i < num ; i++){
                MYSQL_ROW row = mysql_fetch_row(res);
                list[i][0] = atoi(row[1]);  //user_id1
                list[i][1] = atoi(row[2]);  //user_id2
            }
        }
        mysql_free_result(res);
    }
    return num;
}

int mysql_get_friendlist(int uid , int * uid_list , char ** name_list , char ** headimg_list){
    int total = 0;
    char query_str[MAX_SQL_LEN] = { 0 };

    //正向好友列表
    sprintf(query_str , "select `user_relationship`.`user_id2` ,`user`.`username` , `user`.`headimg` \
        from `user_relationship` left join `user` on `user`.`uid` = `user_relationship`.`user_id2` \
        where `user_relationship`.`remark` = 1 and  `user_relationship`.`user_id1`='%d';" , uid);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL ) {
            int num = mysql_num_rows(res);
            for(int i = 0 ; i < num ; i++){
                MYSQL_ROW row = mysql_fetch_row(res);
                uid_list[total] = atoi(row[0]);  //user_id2
                strcpy(name_list[total] , row[1]);     //username
                strcpy(headimg_list[total] , row[2]);   //headimg
                total++;
            }
        }
        mysql_free_result(res);
    }

    //反向好友列表
    sprintf(query_str , "select `user_relationship`.`user_id1` ,`user`.`username` , `user`.`headimg`\
        from `user_relationship` left join `user` on `user`.`uid` = `user_relationship`.`user_id1` \
        where `user_relationship`.`remark` = 1 and  `user_relationship`.`user_id2`='%d';" , uid);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL ) {
            int num = mysql_num_rows(res);
            for(int i = 0 ; i < num ; i++){
                MYSQL_ROW row = mysql_fetch_row(res);
                uid_list[total] = atoi(row[0]);  //user_id2
                strcpy(name_list[total] , row[1]);     //username
                strcpy(headimg_list[total] , row[2]);   //headimg
                total++;
            }
        }
        mysql_free_result(res);
    }
    return total;
}

int mysql_add_user(char * username , char * passwd , int * uid){
    int ret = -1;
    char query_str[MAX_SQL_LEN] = "select `uid` from `user` order by `id` desc limit 1";
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);  
        if (res != NULL) {
            if(mysql_num_rows(res) > 0 &&  mysql_field_count(&mysql) > 0){    //有用户
                MYSQL_ROW row = mysql_fetch_row(res);
                int last_uid = atoi(row[0]);
                *uid = last_uid + 1;
            }else{      //没有用户
                *uid = 10000;
            }
            char insert_str[MAX_SQL_LEN] = { 0 };
            sprintf(insert_str ,  \
                "insert into `user` (uid,username,password,headimg) VALUES ('%d','%s','%s','')" ,\
                *uid , username , passwd);
            //printf("mysql_add_user : %s" , insert_str);
            if(_mysql_real_query(&mysql, insert_str, strlen(insert_str)) == 0){
                ret = mysql_insert_id(&mysql);
            }
        }
        mysql_free_result(res);
    }
    return ret;
}

int mysql_add_friendlist(int from , int to , int remark){
    int ret = -1;
    //先检查好友关系表中是否有这条数据
    char query_str[MAX_SQL_LEN] = { 0 };
    // sprintf(query_str , "select * from `user_relationship` where `user_id1` = '%d' and `user_id2` = '%d'" , from , to);
    // if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
    //     MYSQL_RES * res = mysql_store_result(&mysql);  
    //     if (res != NULL && mysql_num_rows(res) > 0) {       //有这条数据
    //         mysql_free_result(res);
    //         return ret;
    //     }
    //     mysql_free_result(res);
    // }

    //插入数据
    sprintf(query_str , "insert `user_relationship` (user_id1 , user_id2 , remark) values ('%d' , '%d' , '%d')" , \
        from , to , remark);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        ret = mysql_insert_id(&mysql);
    }
    return ret;
}

/**
 * [内部函数]
 * 该函数获取好友关系表中remark字段值
 * 返回值：-1表示没有该条数据；0表示一方发起申请但另一方未通过；1表示建立好友关系
*/
int mysql_get_friendlistremark(int from , int to){
    int ret = -1;
    //先检查好友关系表中是否有这条数据
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "select `remark` from `user_relationship` where `user_id1` = '%d' and `user_id2` = '%d'" , from , to);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);  
        if (res != NULL && mysql_num_rows(res) > 0) {       //有这条数据
            MYSQL_ROW row = mysql_fetch_row(res);
            ret = atoi(row[0]);
        }
        mysql_free_result(res);
    }
    return ret;
}

int mysql_del_relationship(int from , int to){
    int ret = -1;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "delete from `user_relationship` where (`user_id1`='%d' and `user_id2`='%d') or (`user_id1`='%d' and `user_id2`='%d')" , \
        from , to , to , from);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        ret = mysql_affected_rows(&mysql);
    }
    return ret;
}

int mysql_update_friendlist(int from , int to , int remark){
    int ret = -1;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "update `user_relationship` set `remark` = '%d' where `user_id2` = '%d' and `user_id1` = '%d'" , \
        remark , from , to);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        ret = mysql_affected_rows(&mysql);
    }
    return ret;
}

bool mysql_check_login(int uid , char * passwd){
    bool ret = false;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "select `password` from `user` where `uid` = %d" , uid);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL &&  mysql_field_count(&mysql) > 0 && mysql_num_rows(res) > 0) {
            MYSQL_ROW row = mysql_fetch_row(res);
            if(!strcmp(passwd , row[0])){
                ret = true;
            }
        }
        mysql_free_result(res);
    }
    return ret;
}

bool mysql_find_user(int uid , char * username , char * headimg){
    bool ret = false;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "select `username`,`headimg` from `user` where `uid` = '%d'" , uid);
    //printf("%s\n" , query_str);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL &&  mysql_field_count(&mysql) > 0 && mysql_num_rows(res) > 0) {
            MYSQL_ROW row = mysql_fetch_row(res);
            strcpy(username , row[0]);
            strcpy(headimg , row[1]);
            ret = true;
        }
        mysql_free_result(res);
    }
    return ret;
}

// int mysql_get_msg_num(int uid){
//     int num = 0;
//     char query_str[MAX_SQL_LEN] = { 0 };
//     sprintf(query_str , "select count(*) from `chatmsg` where `targetid` = %d" , uid);
//     if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
//         MYSQL_RES * res = mysql_store_result(&mysql);
//         if (res != NULL &&  mysql_field_count(&mysql) > 0 && mysql_num_rows(res) > 0) {
//             MYSQL_ROW row = mysql_fetch_row(res);
//             num = atoi(row[0]);
//         }
//         mysql_free_result(res);
//     }
//     return num;
// }

int mysql_update_pass(int uid , char * newpasswd){
    bool ret = -1;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "update `user` set `password`= '%s' where `uid` = '%d'" ,newpasswd , uid);
    //printf("%s\n" , query_str);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        ret = mysql_affected_rows(&mysql);
    }
    return ret;
}

int mysql_update_userinfo(int uid , char * username , char * headimg){
    bool ret = 0;
    if(username != NULL){
        char query_str[MAX_SQL_LEN] = { 0 };
        sprintf(query_str , "update `user` set `username`= '%s' where `uid` = '%d'" , username , uid);
        if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
            ret += mysql_affected_rows(&mysql);
        }else{
            return ret;
        }
    }
    if(headimg != NULL){
        char query_str[MAX_SQL_LEN] = { 0 };
        sprintf(query_str , "update `user` set `headimg`= '%s' where `uid` = '%d'" , headimg , uid);
        if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
            ret += mysql_affected_rows(&mysql);
        }else{
            return ret;
        }
    }
    return ret;
}

int mysql_push_msg_queue(int fromuid , int touid , char *msg){
    bool ret = -1;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "insert into `chatmsg` (senderid , targetid , msgcontent , remark) values ('%d' , '%d', '%s' , '0')" ,fromuid , touid , msg);
    //printf("%s\n" , query_str);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        ret = mysql_affected_rows(&mysql);
    }
    return ret;
}

int mysql_pull_msg(int uid , char msg[20][MESSAGE_BUFF_MAX_LEN]){
    int num = 0;
    char query_str[MAX_SQL_LEN] = { 0 };
    sprintf(query_str , "select `msgcontent` from `chatmsg` where `targetid` = '%d' and `remark` = 0 order by `create_time` limit 20" , uid);
    //printf("%s\n" , query_str);
    if(_mysql_real_query(&mysql, query_str, strlen(query_str)) == 0){
        MYSQL_RES * res = mysql_store_result(&mysql);
        if (res != NULL) {
            num = mysql_num_rows(res);
            for(int i = 0 ; i < num ; i ++){
                MYSQL_ROW row = mysql_fetch_row(res);
                strcpy(msg[i] , row[0]);
            }
        }
        mysql_free_result(res);
    }
    //查完之后要删除消息
    sprintf(query_str , "update `chatmsg` set `remark` = '1' where `targetid` = '%d' and `remark` = 0 order by `create_time` limit 20" , uid);
    _mysql_real_query(&mysql, query_str, strlen(query_str));
    return num;
}

/* TODO:自定义的查询函数，增加断线检测和重连机制
*  @param mysql 句柄
*  @param query sql查询字符串
*  @param length 查询字符串长度
*  return mysql_real_query返回值  
*/
int _mysql_real_query(MYSQL *mysql, const char *query, unsigned long length){
    int ret = mysql_real_query(mysql, query, length);
    if(ret == CR_SERVER_GONE_ERROR || ret == CR_SERVER_LOST || ret == CR_UNKNOWN_ERROR){
        //重新连接
        mysql_close(mysql);
        if (mysql_init(mysql) == NULL){
            return ret;
        }
        char value = 1;
        mysql_options(mysql, MYSQL_OPT_RECONNECT, &value);
        if (mysql_real_connect(mysql , m_host , m_user , m_pass , m_db , m_port , NULL , 0) == NULL){
            return ret;
        }
        //重新执行查询语句
        ret = mysql_real_query(mysql, query, length);
    }
    return ret;
}